package com.tbox.tbsdk;

import android.bluetooth.BluetoothGatt;
import android.util.Log;

import com.lib.util.SPUtils;

/**
 * Created by rui.yang
 * on 2020/12/8
 */
class FrameUnpack {
    private static String tag = "FrameUnpack";

    public class UnpackResult {
        public boolean authenticationFailed = false;    /// 目鉴权失败场景，上层主动断开蓝牙连接
        public boolean illegal = false;     /// 非法帧，长度校验失败，bcc 校验失败，解密失败等
        public byte[] replyFrame = null;    /// 需要回复的帧，ack 确认帧 or 业务确认帧
        public byte serialNumber = -1;      /// 帧流水号
    }

    public void setConnectingListener(TBoxSDK.DeviceConnectingListener connectingListener) {
        this.connectingListener = connectingListener;
    }

    private TBoxSDK.DeviceConnectingListener connectingListener;

    public void setControlListener(TBoxSDK.DeviceControlListener controlListener) {
        this.controlListener = controlListener;
    }

    private TBoxSDK.DeviceControlListener controlListener;

    public UnpackResult unpackFrame(byte[] frame) {
        UnpackResult result = new UnpackResult();

        if (frame == null || frame.length < 10 /* 帧内容为零时至少长度为 10 */) {
            Log.e(tag, "接收帧异常");
            result.illegal = true;
            return result;
        }

        /// 校验长度
        if (frame.length != frame[2]) {
            Log.d(tag, "接收帧长度校验失败，帧标识长度：" + frame[2] + ", 帧实际长度：" + frame.length);
            result.illegal = true;
            return result;
        }

        /// bcc 校验
        byte bcc = ByteUtil.bcc(frame, 0, frame.length - 3);
        if (frame[frame.length - 3] != bcc) {
            Log.d(tag, "接收帧 bcc 校验失败，帧标识 bcc：" + frame[frame.length - 3] + ", 帧实际 bcc：" + bcc);
            result.illegal = true;
            return result;
        }

        /// 帧流水号
        result.serialNumber = frame[4];

        /// 解包体
        byte[] data = getFrameContentData(frame);

        if (frame[5] == 0x01 && frame[6] == 0x01) {
            /// 鉴权响应
            Log.d(tag, "接收到鉴权响应帧");
            unpackAuthenticationFrame(data, result);

        } else if (frame[5] == 0x03 && frame[6] == 0x01) {
            /// 车辆状态同步
            Log.d(tag, "接收到车辆状态同步帧");
            unpackStatusSyncFrame(data, result);

        } else if (frame[5] == 0x02 && frame[6] == 0x01) {
            /// 车辆控制反馈
            Log.d(tag, "接收到车辆控制反馈帧");
            unpackControlFrame(data, result);
        }

        return result;
    }

    private void unpackAuthenticationFrame(byte[] data, UnpackResult result) {
        /// 55551a0201010105bb76714403bf7ab1681a5017d4f45ed8aaaa
        if (data != null && data.length > 0 && data[0] == 0x00) {
            Log.d(tag, "鉴权成功");
            result.authenticationFailed = false;
            if (connectingListener != null) {
                connectingListener.onDeviceConnected();
            }
        } else {
            Log.d(tag, "鉴权失败");
            result.authenticationFailed = true;
        }
    }

    private void unpackStatusSyncFrame(byte[] data, UnpackResult result) {
        /// 55551a020303015b3cf002284aed3e8161f43d0d644992a6aaaa
        if (data != null && data.length > 0 && data.length > 8) {
            Log.d("lanbin", "车辆状态同步：锁状态[" + data[6] + "]  防护状态[" + data[7] +"]  acc 状态[" + data[8] + "]");
            SPUtils.getInstance().put(Constant.KEY_ACC_STATUS, data[8]);
          Log.e("lanbin", SPUtils.getInstance().getInt(Constant.KEY_ACC_STATUS)+"");

            /// ACK 确认帧
            /// result.replyFrame = FramePackage.packageAckFrame(result.serialNumber);
            /// 状态同步确认帧
            result.replyFrame = FramePackage.packageStatusSyncAck(result.serialNumber, (byte)0x00/*成功*/);

            if (connectingListener != null) {
                connectingListener.onDeviceStatusSync(
                        TBoxSDK.LockStatus.of(data[6]),
                        TBoxSDK.DefendStatus.of(data[7]),
                        TBoxSDK.ACCStatus.of(data[8])
                        );
            }
        } else {
            Log.d(tag, "车辆状态同步解析失败");
            result.illegal = true;
        }
    }

    private void unpackControlFrame(byte[] data, UnpackResult result) {
        /// 55551a02140201f4369933102d47752a47b68b8ed140caedaaaa
        if (data != null && data.length > 0 && data.length > 0) {
            Log.d(tag, "控制指令反馈结果：[" + data[0] + "]");
            if (controlListener != null) {
                if (data[0] == 0x00) {
                    controlListener.onControlSuccess();
                } else {
                    controlListener.onControlFailed(data[0]);
                }
            }
        } else {
            Log.d(tag, "控制指令反馈结果解析失败");
            result.illegal = true;
            controlListener.onControlFailed(-1);
        }
    }

    private byte[] getFrameContentData(byte[] frame) {
        String AES128SecretKey = SPUtils.getInstance().getString(Constant.KEY_AES);

        byte[] data = AesUtil.decrypt(ByteUtil.subByte(frame, 7, frame.length - 10), AES128SecretKey);
        return data;
    }
}
